home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_init_finish.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  11.4 KB  |  360 lines

  1. /*
  2.  
  3.  
  4.     dwarf_init_finish.c
  5.     $Revision: 1.33 $   $Date: 1994/06/17 02:39:38 $
  6.  
  7. */
  8.  
  9. #include <libelf.h>
  10. #include <stdio.h>
  11. #include <sys/stat.h>
  12. #include <sys/types.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15.  
  16. #include "dwarf_incl.h"
  17.  
  18. #define DWARF_DBG_ERROR(dbg,errval,retval) \
  19.      _dwarf_error(dbg, error, errval); return(retval);
  20.  
  21. #define FALSE    0
  22. #define TRUE    1
  23.  
  24. extern Elf64_Ehdr *elf64_getehdr (Elf *);
  25. extern Elf64_Shdr *elf64_getshdr (Elf_Scn *);
  26.  
  27. /*
  28.     Given an Elf ptr, set up dbg with pointers
  29.     to all the Dwarf data sections.
  30.     Return NULL on error.
  31.  
  32.     This function is also responsible for determining
  33.     whether the given object contains Dwarf information
  34.     or not.  The test currently used is that it contains
  35.     either a .debug_info or a .debug_frame section.  If 
  36.     not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to 
  37.     return DW_DLV_NO_ENTRY.  Earlier, we had thought of using only 
  38.     the presence/absence of .debug_info to test, but we 
  39.     added .debug_frame since there could be stripped objects 
  40.     that have only a .debug_frame section for exception 
  41.     processing.
  42.     DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR
  43. */
  44. static int
  45. _dwarf_setup (
  46.     Dwarf_Debug     dbg,
  47.     Elf             *elf,
  48.     Dwarf_Error     *error
  49. )
  50. {
  51.     Elf32_Ehdr      *ehdr32;
  52.     Elf64_Ehdr        *ehdr64;
  53.     Elf32_Shdr      *shdr32;
  54.     Elf64_Shdr      *shdr64;
  55.     Elf_Scn         *scn;
  56.     Elf_Data        *data;
  57.     char            *scn_name;
  58.     char        *ehdr_ident;
  59.     int            is_64bit;
  60.     int            foundDwarf;
  61.  
  62.     foundDwarf = FALSE;
  63.     dbg->de_elf = elf;
  64.  
  65.     if ((ehdr_ident=elf_getident(elf,NULL)) == NULL)
  66.     {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_GETIDENT_ERROR,DW_DLV_ERROR);}
  67.  
  68.     is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
  69.     dbg->de_length_size = is_64bit ? 8 : 4;
  70.  
  71.     if (is_64bit) {
  72.     if ((ehdr64=elf64_getehdr(elf)) == NULL)
  73.         {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_GETEHDR_ERROR,DW_DLV_ERROR);}
  74.     }
  75.     else {
  76.     if ((ehdr32=elf32_getehdr(elf)) == NULL)
  77.         {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_GETEHDR_ERROR,DW_DLV_ERROR);}
  78.     }
  79.  
  80.     scn = NULL;
  81.     while ((scn=elf_nextscn(elf,scn)) != NULL) {
  82.  
  83.     if (is_64bit) {
  84.             if ((shdr64=elf64_getshdr(scn)) == NULL)
  85.                 {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_GETSHDR_ERROR,DW_DLV_ERROR);}
  86.             if ((scn_name=elf_strptr(elf,ehdr64->e_shstrndx,shdr64->sh_name)) 
  87.         == NULL) {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_STRPTR_ERROR,DW_DLV_ERROR);}
  88.     }
  89.     else {
  90.             if ((shdr32=elf32_getshdr(scn)) == NULL)
  91.                 {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_GETSHDR_ERROR,NULL);}
  92.             if ((scn_name=elf_strptr(elf,ehdr32->e_shstrndx,shdr32->sh_name)) 
  93.         == NULL) {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_STRPTR_ERROR,DW_DLV_ERROR);}
  94.     }
  95.  
  96.         if (strncmp(scn_name,".debug_",7)) continue;
  97.  
  98.         else if (strcmp(scn_name,".debug_info") == 0) {
  99.             if (dbg->de_debug_info != NULL)
  100.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLV_ERROR);}
  101.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  102.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_INFO_NULL,DW_DLV_ERROR);}
  103.             dbg->de_debug_info = data->d_buf;
  104.             dbg->de_debug_info_size = data->d_size;
  105.         foundDwarf = TRUE;
  106.         }
  107.  
  108.         else if (strcmp(scn_name,".debug_abbrev") == 0) {
  109.             if (dbg->de_debug_abbrev != NULL)
  110.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLV_ERROR);}
  111.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  112.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_ABBREV_NULL,DW_DLV_ERROR);}
  113.             dbg->de_debug_abbrev = data->d_buf;
  114.             dbg->de_debug_abbrev_size = data->d_size;
  115.         }
  116.  
  117.         else if (strcmp(scn_name,".debug_aranges") == 0) {
  118.             if (dbg->de_debug_aranges != NULL)
  119.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_ARANGES_DUPLICATE,DW_DLV_ERROR);}
  120.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  121.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_ARANGES_NULL,DW_DLV_ERROR);}
  122.             dbg->de_debug_aranges = data->d_buf;
  123.             dbg->de_debug_aranges_size = data->d_size;
  124.         }
  125.  
  126.         else if (strcmp(scn_name,".debug_line") == 0) {
  127.             if (dbg->de_debug_line != NULL)
  128.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_LINE_DUPLICATE,DW_DLV_ERROR);}
  129.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  130.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_LINE_NULL,DW_DLV_ERROR);}
  131.             dbg->de_debug_line = data->d_buf;
  132.             dbg->de_debug_line_size = data->d_size;
  133.         }
  134.  
  135.         else if (strcmp(scn_name,".debug_frame") == 0) {
  136.             if (dbg->de_debug_frame != NULL)
  137.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_FRAME_DUPLICATE,DW_DLV_ERROR);}
  138.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  139.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_FRAME_NULL,DW_DLV_ERROR);}
  140.             dbg->de_debug_frame = data->d_buf;
  141.             dbg->de_debug_frame_size = data->d_size;
  142.         foundDwarf = TRUE;
  143.         }
  144.  
  145.         else if (strcmp(scn_name,".debug_loc") == 0) {
  146.             if (dbg->de_debug_loc != NULL)
  147.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_LOC_DUPLICATE,DW_DLV_ERROR);}
  148.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  149.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_LOC_NULL,DW_DLV_ERROR);}
  150.             dbg->de_debug_loc = data->d_buf;
  151.             dbg->de_debug_loc_size = data->d_size;
  152.         }
  153.  
  154.         else if (strcmp(scn_name,".debug_macinfo") == 0) {
  155.             if (dbg->de_debug_macinfo != NULL)
  156.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_MACINFO_DUPLICATE,DW_DLV_ERROR);}
  157.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  158.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_MACINFO_NULL,DW_DLV_ERROR);}
  159.             dbg->de_debug_macinfo = data->d_buf;
  160.             dbg->de_debug_macinfo_size = data->d_size;
  161.         }
  162.  
  163.         else if (strcmp(scn_name,".debug_pubnames") == 0) {
  164.             if (dbg->de_debug_pubnames != NULL)
  165.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_PUBNAMES_DUPLICATE,DW_DLV_ERROR);}
  166.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  167.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_PUBNAMES_DUPLICATE,DW_DLV_ERROR);}
  168.             dbg->de_debug_pubnames = data->d_buf;
  169.             dbg->de_debug_pubnames_size = data->d_size;
  170.         }
  171.  
  172.         else if (strcmp(scn_name,".debug_str") == 0) {
  173.             if (dbg->de_debug_str != NULL)
  174.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_STR_DUPLICATE,DW_DLV_ERROR);}
  175.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  176.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_STR_NULL,DW_DLV_ERROR);}
  177.             dbg->de_debug_str = data->d_buf;
  178.             dbg->de_debug_str_size = data->d_size;
  179.         }
  180.  
  181.         else if (strcmp(scn_name,".debug_funcnames") == 0) {
  182.             if (dbg->de_debug_funcnames != NULL)
  183.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,DW_DLV_ERROR);}
  184.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  185.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_FUNCNAMES_NULL,DW_DLV_ERROR);}
  186.             dbg->de_debug_funcnames = data->d_buf;
  187.             dbg->de_debug_funcnames_size = data->d_size;
  188.         }
  189.  
  190.         else if (strcmp(scn_name,".debug_typenames") == 0) {
  191.             if (dbg->de_debug_typenames != NULL)
  192.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_TYPENAMES_DUPLICATE,DW_DLV_ERROR);}
  193.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  194.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_TYPENAMES_NULL,DW_DLV_ERROR);}
  195.             dbg->de_debug_typenames = data->d_buf;
  196.             dbg->de_debug_typenames_size = data->d_size;
  197.         }
  198.  
  199.         else if (strcmp(scn_name,".debug_varnames") == 0) {
  200.             if (dbg->de_debug_varnames != NULL)
  201.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_VARNAMES_DUPLICATE,DW_DLV_ERROR);}
  202.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  203.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_VARNAMES_NULL,DW_DLV_ERROR);}
  204.             dbg->de_debug_varnames = data->d_buf;
  205.             dbg->de_debug_varnames_size = data->d_size;
  206.         }
  207.  
  208.         else if (strcmp(scn_name,".debug_weaknames") == 0) {
  209.             if (dbg->de_debug_weaknames != NULL)
  210.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,DW_DLV_ERROR);}
  211.             if ((data=elf_getdata(scn,0)) == NULL || data->d_size == 0)
  212.                 {DWARF_DBG_ERROR(dbg,DW_DLE_DEBUG_WEAKNAMES_NULL,DW_DLV_ERROR);}
  213.             dbg->de_debug_weaknames = data->d_buf;
  214.             dbg->de_debug_weaknames_size = data->d_size;
  215.         }
  216.     }
  217.     if(foundDwarf) {
  218.     return DW_DLV_OK;
  219.     }
  220.  
  221.     return(DW_DLV_NO_ENTRY);
  222. }
  223.  
  224.  
  225. /*
  226.     The basic dwarf initializer function for consumers.
  227.     Return NULL on error.
  228. */
  229. int
  230. dwarf_init (
  231.     int             fd,
  232.     Dwarf_Unsigned  access,
  233.     Dwarf_Handler   errhand,
  234.     Dwarf_Ptr       errarg,
  235.     Dwarf_Debug     * ret_dbg,
  236.     Dwarf_Error     *error
  237. )
  238. {
  239.     Dwarf_Debug     dbg;
  240.     struct stat     fstat_buf;
  241.     Elf             *elf;
  242.     int res;
  243.  
  244.     dbg = _dwarf_get_debug();
  245.     if (dbg == NULL)
  246.         {DWARF_DBG_ERROR(dbg,DW_DLE_DBG_ALLOC,DW_DLV_ERROR);}
  247.     dbg->de_errhand = errhand;
  248.     dbg->de_errarg = errarg;
  249.  
  250.     if (fstat(fd,&fstat_buf) != 0)
  251.         {DWARF_DBG_ERROR(dbg,DW_DLE_FSTAT_ERROR,DW_DLV_ERROR);}
  252.     if (!S_ISREG(fstat_buf.st_mode))
  253.         {DWARF_DBG_ERROR(dbg,DW_DLE_FSTAT_MODE_ERROR,DW_DLV_ERROR);}
  254.  
  255.     if (access != DW_DLC_READ)
  256.         {DWARF_DBG_ERROR(dbg,DW_DLE_INIT_ACCESS_WRONG,DW_DLV_ERROR);}
  257.     dbg->de_access = access;
  258.  
  259.     elf_version(EV_CURRENT); 
  260.     if ((elf=elf_begin(fd,ELF_C_READ,0)) == NULL)
  261.         {DWARF_DBG_ERROR(dbg,DW_DLE_ELF_BEGIN_ERROR,DW_DLV_ERROR);}
  262.  
  263.     if ((res =_dwarf_setup(dbg, elf,  error)) != DW_DLV_OK) {
  264.     free(dbg);
  265.     return(res);
  266.     }
  267.  
  268.     dbg = _dwarf_setup_debug(dbg);
  269.     if (dbg == NULL) {
  270.         {DWARF_DBG_ERROR(dbg,DW_DLE_DBG_ALLOC,DW_DLV_ERROR);}
  271.     return(DW_DLV_ERROR);
  272.     }
  273.  
  274.     *ret_dbg = dbg;
  275.     return(DW_DLV_OK);
  276. }
  277.  
  278.  
  279. /*
  280.     The alternate dwarf setup call for consumers
  281. */
  282. int
  283. dwarf_elf_init (
  284.     Elf             *elf_file_pointer,
  285.     Dwarf_Unsigned  access,
  286.     Dwarf_Handler   errhand,
  287.     Dwarf_Ptr       errarg,
  288.     Dwarf_Debug     * ret_dbg,
  289.     Dwarf_Error     *error
  290. )
  291. {
  292.     Dwarf_Debug     dbg;
  293.     int res;
  294.  
  295.     dbg = _dwarf_get_debug();
  296.     if (dbg == NULL)
  297.         {DWARF_DBG_ERROR(dbg,DW_DLE_DBG_ALLOC,DW_DLV_ERROR);}
  298.     dbg->de_errhand = errhand;
  299.     dbg->de_errarg = errarg;
  300.  
  301.     if (access != DW_DLC_READ)
  302.         {DWARF_DBG_ERROR(dbg,DW_DLE_INIT_ACCESS_WRONG,DW_DLV_ERROR);}
  303.     dbg->de_access = access;
  304.  
  305.     if((res =_dwarf_setup(dbg, elf_file_pointer,  error)) !=DW_DLV_OK){
  306.     free(dbg);
  307.     return(res);
  308.     }
  309.  
  310.     dbg = _dwarf_setup_debug(dbg);
  311.     if (dbg == NULL) {
  312.         {DWARF_DBG_ERROR(dbg,DW_DLE_DBG_ALLOC,DW_DLV_ERROR);}
  313.     return(DW_DLV_ERROR);
  314.     }
  315.     *ret_dbg = dbg;
  316.     return(DW_DLV_OK);
  317. }
  318.  
  319.  
  320. /*
  321.     Frees all memory that was not previously freed
  322.     by dwarf_dealloc.
  323.     Aside from certain categories.
  324. */ 
  325. int
  326. dwarf_finish (
  327.     Dwarf_Debug        dbg,
  328.     Dwarf_Error        *error
  329. )
  330. {
  331.     int res = _dwarf_free_all_of_one_debug(dbg);
  332.     if(res == DW_DLV_ERROR) {
  333.         {DWARF_DBG_ERROR(dbg,DW_DLE_DBG_ALLOC,DW_DLV_ERROR);}
  334.     }
  335.     return res;
  336.  
  337.     
  338. }
  339.  
  340.  
  341. /*
  342.     This function returns the Elf * pointer
  343.     associated with a Dwarf_Debug.
  344. */
  345. int
  346. dwarf_get_elf (
  347.     Dwarf_Debug        dbg,
  348.     Elf   **        elf,
  349.     Dwarf_Error        *error
  350. )
  351. {
  352.     if (dbg == NULL) {
  353.     _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
  354.     return(DW_DLV_ERROR);
  355.     }
  356.  
  357.     *elf = dbg->de_elf;
  358.     return(DW_DLV_OK);
  359. }
  360.